#ifndef SINGLETON_H
#define SINGLETON_H
#include <mutex>

template <typename T> class singleton {
public:
  template <typename... Args> static T *getInstance(Args &&...args) {
    if (!instance) {
      std::lock_guard<std::mutex> gLock(_mutex);
      if (nullptr == instance) {
        instance = new T(std::forward<Args>(args)...);
      }
    }
    return instance;
  }

  static void destroy() {
    if (instance) {
      delete instance;
      instance = nullptr;
    }
  }

public:
  explicit singleton() = delete;
  singleton(const singleton &) = delete;
  singleton &operator=(const singleton &) = delete;
  //~Singleton();

private:
  static T *instance;
  static std::mutex _mutex;
};

template <typename T> T *singleton<T>::instance = nullptr;

template <typename T> std::mutex singleton<T>::_mutex;

#endif // SINGLETON_H
